package cc.rengu.igas.cops.core.service.trans.unionpay;

import cc.rengu.igas.cops.common.enums.*;
import cc.rengu.igas.cops.common.util.QrCodeUtil;
import cc.rengu.igas.cops.facade.request.BankB2cQrCodeQueryRequest;
import cc.rengu.igas.cops.facade.response.BankB2cQrCodeQueryResponse;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.QrCodeInfo;
import cc.rengu.igas.share.core.realize.BompService;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.BompServiceImpl;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.RiskMonitorInfo;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;

import java.util.List;

/**
 * 被扫-- 二维码校验查询接口
 * 兼容老平台 801069接口
 * 【手机】-->【ESB】-->【支付平台】
 *
 * @author panky
 * @version 1.0.0 创建时间：
 */
public class BankB2cQrCodeQueryService extends BizBaseService implements TransCustomImpl {

    @Override
    protected Object beforeBizProcess() throws Exception {
        BankB2cQrCodeQueryRequest bankB2cQrCodeQueryRequest = new BankB2cQrCodeQueryRequest();
        ConvertUtil.convertOutput(bankB2cQrCodeQueryRequest);
        return bankB2cQrCodeQueryRequest;
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {
        // 录入参数
        BankB2cQrCodeQueryRequest bankB2cQrCodeQueryRequest = (BankB2cQrCodeQueryRequest) request;
        // 行号
        String instId = bankB2cQrCodeQueryRequest.getHeader().getInstId();

        //二维码不能为空
        if (StringUtil.isEmptyOrNull(bankB2cQrCodeQueryRequest.getReqCodeUrl())) {
            rglog.error("二维码参数为空, instId:<{}>!", bankB2cQrCodeQueryRequest.getHeader().getInstId());
            throw new BizException(RespCodeEnum.PARAM_ERROR.getRespCode(), RespCodeEnum.PARAM_ERROR.getRespDesc());
        }

        /*处理老平台收单码*/
        if (bankB2cQrCodeQueryRequest.getReqCodeUrl().contains("pay/PYCodePay.do")) {
            bankB2cQrCodeQueryRequest.setReqCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl().replace("pay/PYCodePay.do", "epay-h5/COPS/qr-code-payment"));
        }
        //去掉C1码中的tt和si参数，用于数据库查询
        String qrCodeUrl = QrCodeUtil.filterTtAndSi(bankB2cQrCodeQueryRequest.getReqCodeUrl());

        //查询二维码
        BompService bompService = new BompServiceImpl();
        QrCodeInfo qrCodeInfo = bompService.getQrCodeInfo(instId, qrCodeUrl, null);

        String mchntNo = null;
        BankB2cQrCodeQueryResponse response = new BankB2cQrCodeQueryResponse();
        response.setCodeFlag(BackB2CQrCodeFlagEnum.SELF.getValue());
        if (qrCodeInfo != null) {
            //增加对二维码状态和时效的校验
            String currentTime = DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS");
            if (!qrCodeInfo.getQrStatus().equals("00")) {
                rglog.info("当前二维码未绑定商户，不可用.qrCodeBindStatus:<{}>", qrCodeInfo.getBindStatus());
                throw new BizException(RespCodeEnum.GET_QRCODE_INVALID.getRespCode(), RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
            } else if (QrBindStatusEnum.UNBIND.getBindStatus().equals(qrCodeInfo.getBindStatus())) {
                rglog.info("当前二维码未绑定商户，不可用.qrCodeBindStatus:<{}>", qrCodeInfo.getBindStatus());
                throw new BizException(RespCodeEnum.GET_QRCODE_INVALID.getRespCode(), RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
            } else if (!StringUtil.isEmptyOrNull(qrCodeInfo.getEffectiveTime())
                    && DateUtil.compareTime(currentTime, qrCodeInfo.getEffectiveTime(), "yyyy-MM-dd HH:mm:ss.SSS") < 0) {
                rglog.error("二维码未生效!");
                throw new BizException(RespCodeEnum.GET_QRCODE_INVALID.getRespCode(), RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
            } else if (!StringUtil.isEmptyOrNull(qrCodeInfo.getExpiryTime())
                    && DateUtil.compareTime(currentTime, qrCodeInfo.getExpiryTime(), "yyyy-MM-dd HH:mm:ss.SSS") > 0) {
                rglog.error("二维码已失效!");
                throw new BizException(RespCodeEnum.GET_QRCODE_INVALID.getRespCode(), RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
            }
            //静态码
            mchntNo = qrCodeInfo.getMchntNo();

            //組裝信息
            if (!StringUtil.isEmptyOrNull(qrCodeInfo.getSrcAmtType())) {
                if (qrCodeInfo.getSrcAmtType().equals("0")) {
                    //客户数据
                    response.setAmtSource(BackB2CQrCodeAmtSourceEnum.CLIENT_INPUT.getValue());
                } else {
                    //固定金额
                    response.setAmtSource(BackB2CQrCodeAmtSourceEnum.STATIC.getValue());
                }
            }
            response.setMchntCd(qrCodeInfo.getMchntNo());
            response.setTransSource(BackB2CQrCodeTransSourceEnum.QR_CODE.getValue());//静态扫码
            response.setTransAmt(qrCodeInfo.getTransAmt());
            response.setApplyDatetime(qrCodeInfo.getEffectiveTime());

            //他行码
            if (!StringUtil.isEmptyOrNull(qrCodeInfo.getRelationQrCode())
                    && qrCodeInfo.getRelationQrCode().equals(qrCodeUrl)) {
                response.setCodeFlag(BackB2CQrCodeFlagEnum.THEIR.getValue());
                qrCodeUrl = qrCodeInfo.getQrUrl();
            }
        } else {
            //动态码
            //二维码为空后，查新订单表
            UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
            UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByOrderUrl(instId, qrCodeUrl);
            //未知二維碼
            if (userOrderInfo == null) {
                //未知二维码
                response.setCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
                response.setReqCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
                response.setCodeFlag(BackB2CQrCodeFlagEnum.OTHER.getValue());
                response.setTransSource(BackB2CQrCodeFlagEnum.OTHER.getValue());
                BizResponse bizResponse = new BizResponse();
                bizResponse.setResult(response);// 返回结果
                bizResponse.setRspSysId(AppParamConstant.IGAS);
                bizResponse.setRespCode(RespCodeEnum.GET_QRCODE_INVALID.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
                return bizResponse;
            }

            MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
            List<MchntOrderInfo> mchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(instId, userOrderInfo.getSysSeqNum());
            if (mchntOrderInfoList == null || mchntOrderInfoList.isEmpty()) {
                //未知二维码
                response.setCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
                response.setReqCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
                response.setCodeFlag(BackB2CQrCodeFlagEnum.OTHER.getValue());
                response.setTransSource(BackB2CQrCodeFlagEnum.OTHER.getValue());
                BizResponse bizResponse = new BizResponse();
                bizResponse.setResult(response);// 返回结果
                bizResponse.setRspSysId(AppParamConstant.IGAS);
                bizResponse.setRespCode(RespCodeEnum.GET_QRCODE_INVALID.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.GET_QRCODE_INVALID.getRespDesc());
                return bizResponse;
            }

            MchntOrderInfo mchntOrderInfo = mchntOrderInfoList.get(mchntOrderInfoList.size() - 1);
            //商户号
            mchntNo = mchntOrderInfo.getMchntNo();
            //组装信息

            response.setAmtSource(BackB2CQrCodeAmtSourceEnum.STATIC.getValue());
            response.setTransSource(BackB2CQrCodeTransSourceEnum.PAYMENT.getValue());//收单前置
            response.setTraceNo(mchntOrderInfo.getSysSeqNum());//下单请求流水号
            response.setExpireTime(userOrderInfo.getOrderExpiryTime());//订单失效时间
            response.setTransAmt(mchntOrderInfo.getOrderAmt());//交易金额
            response.setMchntOrderId(mchntOrderInfo.getMchntOrderId());
        }

        //商户号不为空时校验商户信息
        MchntService mchntService = new MchntServiceImpl();
        if (!StringUtil.isEmptyOrNull(mchntNo)) {
            if (mchntService.checkMchntStatus(instId, mchntNo)) {
                rglog.error("商户<{}>状态异常!", mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
            }

            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
            //一级商户名
            response.setMchntNm(mchntInfo.getMchntName());
        } else {
            //返回空值，防止手机银行扫码抛错
            mchntNo = "0000000000";
            response.setMchntNm("无效商户");
        }

        //組裝商戶信息
        response.setCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
        response.setReqCodeUrl(bankB2cQrCodeQueryRequest.getReqCodeUrl());
        response.setMchntCd(mchntNo);
        response.setCodeId(bankB2cQrCodeQueryRequest.getHeader().getTraceNo());
        response.setCodeType("1");
        response.setQrCodeUrl(createQrCodeUrl(instId, qrCodeUrl));

        /** 861、867行的主扫页面标题显示为云闪付 */
        if (instId.equals("861")
                || instId.equals("867")) {
            response.setTitle("云闪付");
        } else {
            response.setTitle("扫一扫");
        }

        BizResponse bizResponse = new BizResponse();
        bizResponse.setResult(response);// 返回结果
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {
        BankB2cQrCodeQueryResponse retResponse = (BankB2cQrCodeQueryResponse) response.getResult();
        ConvertUtil.convertInput(retResponse);
    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        return null;
    }

    /**
     * 拼接手机银行跳转二维码路径参数
     *
     * @param instId
     * @param codeUrl
     * @return
     * @throws Exception
     */
    private String createQrCodeUrl(String instId, String codeUrl) throws Exception {
        SysParamService paramService = new SysParamServiceImpl();
        SysParam sysParam = paramService.getSysParamInfo(instId, "OPMS_SYS_PARAM", "T00CO021QR");

        StringBuilder sbd = new StringBuilder();
        sbd.append(sysParam.getParamValue());
        sbd.append(codeUrl.substring(codeUrl.indexOf("?")));
        if (codeUrl.indexOf("payCodeInfo") == -1) {
            sbd.append("&payCodeInfo=");
            sbd.append(StringUtil.binaryToBase64String(codeUrl.getBytes("UTF-8")));
        }
        return sbd.toString();
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
